#include <ALEstd.h>
#include <CInput.h>
#pragma warning( disable : 4244)

CInput::CInput( HWND hwnd )
{
    //save window handle
    window = hwnd;
    
    //create DirectInput object
    DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
        IID_IDirectInput8, (void**)&di, NULL );
    
    //initialize keyboard
    di->CreateDevice(GUID_SysKeyboard, &keyboard, NULL);
    keyboard->SetDataFormat( &c_dfDIKeyboard );
    keyboard->SetCooperativeLevel( window, 
        DISCL_FOREGROUND | DISCL_NONEXCLUSIVE );
    keyboard->Acquire();
    
    //initialize mouse
    di->CreateDevice(GUID_SysMouse, &mouse, NULL);
    mouse->SetDataFormat(&c_dfDIMouse);
    mouse->SetCooperativeLevel(window,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE);
    mouse->Acquire();
}
    
CInput::~CInput()
{
	SAFE_RELEASE(keyboard);
	SAFE_RELEASE(mouse);
	SAFE_RELEASE(di);
}
    
void CInput::Update()
{
    //poll state of the keyboard
    keyboard->Poll();
    if (!SUCCEEDED(keyboard->GetDeviceState(256,(LPVOID)&keyState)))
    {
        //keyboard device lost, try to re-acquire
        keyboard->Acquire();
    }

    //poll state of the mouse
    mouse->Poll();
    if (!SUCCEEDED(mouse->GetDeviceState(sizeof(DIMOUSESTATE),&mouseState)))
    {
        //mouse device lose, try to re-acquire
        mouse->Acquire();
    }
    
    //get mouse position on screen
    GetCursorPos(&position);
    ScreenToClient(window, &position);
    
}

void CInput::SendEvents()
{
	static bool bButtonDown[3] = {false, false, false};
	for (int i = 0; i < 3; i++)
	{
		if (GetMouseButton(i))
		{
			bButtonDown[i] = true;
			IEventPtr mouseDown(ALE_NEW Event_Mouse_Down(i));
			IEventManager::Get()->VQueueEvent(mouseDown);
		}
		else if(bButtonDown[i])
		{
			bButtonDown[i] = false;
			IEventPtr mouseUp(ALE_NEW Event_Mouse_Up(i));
			IEventManager::Get()->VQueueEvent(mouseUp);
		}
	}

	static POINT lastPos = position;
	if (lastPos.x != position.x || lastPos.y != position.y)
	{
		Vec2 pos(position.x, position.y);
		Vec2 lastpos(lastPos.x, lastPos.y);
		IEventPtr mouseMove(ALE_NEW Event_Mouse_Move(pos, lastpos));
		IEventManager::Get()->VQueueEvent(mouseMove);

		lastPos = position;
	}

	if(GetDeltaX() || GetDeltaY())
	{
		IEventPtr mouseMotion(ALE_NEW Event_Mouse_Motion(GetDeltaX(), GetDeltaY()));
		IEventManager::Get()->VQueueEvent(mouseMotion);
	}

	static char lastKeyState[256];
	for (int i = 0; i < 256; i++)
	{
		if(GetKeyState(i) & 0x80)
		{
			lastKeyState[i] = GetKeyState(i);
			IEventPtr keyDown(ALE_NEW Event_Key_Down(i));
			IEventManager::Get()->VQueueEvent(keyDown);
		}
		else if (lastKeyState[i] & 0x80)
		{
			lastKeyState[i] = GetKeyState(i);
			IEventPtr keyUp(ALE_NEW Event_Key_Up(i));
			IEventManager::Get()->VQueueEvent(keyUp);
		}
	}

}
    
int CInput::GetMouseButton( char button )
{
    return ( mouseState.rgbButtons[button] & 0x80 );
}

#pragma warning( default : 4244)

